﻿using System;
using System.Collections.Generic;
using Bastanteo.Dominio;
using Bastanteo.Persistencia;


namespace Bastanteo.Negocio
{
    public class AdministracionServiceImpl : IAdministracionService
    {
        #region Dependencias
        IClienteDAO clienteDAO = null;
        IBastanteoCombinacionDAO combinacionDAO = null;
        IBastanteoDAO bastanteoDAO = null;
        IGrupoDAO grupoDAO = null;
        IPoderDAO poderDAO = null;
        IRepresentanteDAO representanteDAO = null;
        #endregion

        //PODER________IVAN____________________________________________________________
        #region Operaciones de negocio poder
        public Poder RegistrarPoder(String descripcion, String tipoProducto)
        {
            //Excepción si falta algún dato requerido
            if (descripcion == null || tipoProducto == null)
                throw new DatosInsuficientesException("Faltan datos para crear el Poder");
            //Creación del Poder
            Poder poderACrear = new Poder();
            poderACrear.Descripcion = descripcion;
            poderACrear.TipoProducto = tipoProducto;
            return poderDAO.Crear(poderACrear);
        }

        #endregion

        #region Métodos de soporte para entidad poder
        public Poder CrearPoder(Poder poderACrear)
        {
            if (poderDAO.ListarPoderPorDescripcion(poderACrear.Descripcion) != null)
                throw new EntidadRepetidaException("El Poder ya existe");
            return poderDAO.Crear(poderACrear);
        }

        public Poder ObtenerPoder(Int32 codigo)
        {
            return poderDAO.Obtener(codigo);
        }

        public void EliminarPoder(Int32 PoderAEliminar)
        {
            Poder poderAEliminar = new Poder();
            poderAEliminar = poderDAO.Obtener(PoderAEliminar);

            //Excepción si ya está asignado a un bastanteo
            if (bastanteoDAO.ObtenerPorPoder(PoderAEliminar) != null)
                throw new EntidadRelacionadaException("El poder ya está asignado a un bastanteo!!!");

            poderDAO.Eliminar(poderAEliminar);
        }

        public Poder ModificarPoder(Poder poderAModificar)
        {
            return poderDAO.Modificar(poderAModificar);
        }

        public ICollection<Poder> ListarPoderes()
        {
            return poderDAO.ListarTodos();
        }

        public ICollection<Poder> ListarPoderPorDescripcion(string descripcion)
        {
            return poderDAO.ListarPoderPorDescripcion(descripcion);
        }
        #endregion

        //GRUPO________IVAN___________________________________________________________
        #region Operaciones de negocio grupo
        public Grupo RegistrarGrupo(String descripcion)
        {
            //Excepción si falta algún dato requerido
            if (descripcion == null)
                throw new DatosInsuficientesException("Faltan datos para crear el Grupo");
            //Creación del Poder
            Grupo grupoACrear = new Grupo();
            grupoACrear.Descripcion = descripcion;
            return grupoDAO.Crear(grupoACrear);
        }
        #endregion

        #region Métodos de soporte para entidad grupo
        public Grupo CrearGrupo(Grupo grupoACrear)
        {
            if (grupoDAO.ListarPorDescripcion(grupoACrear.Descripcion) != null)
                throw new EntidadRepetidaException("El Grupo ya existe");
            return grupoDAO.Crear(grupoACrear);
        }

        public Grupo ModificarGrupo(Grupo grupoAModificar)
        {
            return grupoDAO.Modificar(grupoAModificar);
        }

        public void EliminarGrupo(Grupo grupoAEliminar)
        {
            grupoDAO.Eliminar(grupoAEliminar);
        }

        public ICollection<Grupo> ListarGrupos()
        {
            return grupoDAO.ListarTodos();
        }

        public Grupo ObtenerGrupo(Int32 codigo)
        {
            return grupoDAO.Obtener(codigo);
        }

        public ICollection<Grupo> ListarPorDescripcion(string descripcion)
        {
            return grupoDAO.ListarPorDescripcion(descripcion);
        }
        #endregion

        //CLIENTE________MAGALY___________________________________________________________
        #region Operaciones de negocio cliente
        public Cliente RegistrarCliente(String ruc, String razonSocial,
            DateTime inicioOperaciones, String tipoEmpresa, Int32 empleados)
        {
            // Excepción si falta algún dato requerido
            if (ruc == null || razonSocial == null || inicioOperaciones == null ||
                tipoEmpresa == null || empleados <= 0)
                throw new DatosInsuficientesException("Faltan datos para crear cliente");
            // Excepción si ya se registrón el mismo cliente (por su RUC)
            if (clienteDAO.ObtenerPorRuc(ruc) != null)
                throw new EntidadRepetidaException("El cliente ya existe");
            // Creación del cliente
            Cliente clienteACrear = new Cliente();
            clienteACrear.Ruc = ruc;
            clienteACrear.RazonSocial = razonSocial;
            clienteACrear.FechaInicioOperaciones = inicioOperaciones;
            clienteACrear.TipoEmpresa = tipoEmpresa;
            clienteACrear.CantidadEmpleados = empleados;
            return clienteDAO.Crear(clienteACrear);
        }
        #endregion

        #region Métodos de soporte para entidad Cliente
        public Cliente CrearCliente(Cliente clienteACrear)
        {
            if (clienteDAO.ObtenerPorRuc(clienteACrear.Ruc) != null)
                throw new EntidadRepetidaException("El cliente ya existe");
            return clienteDAO.Crear(clienteACrear);
        }

        public Cliente ObtenerCliente(Int32 codigo)
        {
            return clienteDAO.Obtener(codigo);
        }

        public Cliente ObtenerXRuc(string ruc)
        {
            return clienteDAO.ObtenerPorRuc(ruc);
        }

        public Cliente ModificarCliente(Cliente clienteAModificar)
        {
            return clienteDAO.Modificar(clienteAModificar);
        }

        public void EliminarCliente(Cliente clienteAEliminar)
        {
            clienteDAO.Eliminar(clienteAEliminar);
        }

        public ICollection<Cliente> ListarClientes()
        {
            return clienteDAO.ListarTodos();
        }

        public ICollection<Cliente> ListarXRuc(String ruc)
        {
            return clienteDAO.ListarTodos();
        }
        #endregion

        //REPRESENTANTE________KAREM___________________________________________________________
        #region Operaciones de negocio

        // Creación del Representante
        public Representante RegistrarRepresentante(Cliente cliente, String TipoDocumento, String NumeroDocumento, String Nombres, String Apellidos, Grupo Grupo, String Cargo)
        {
            // Excepción si falta algún dato requerido
            if (cliente == null || TipoDocumento == null || NumeroDocumento == null || Nombres == null || Apellidos == null || Grupo == null || Cargo == null)
                throw new DatosInsuficientesException("Faltan datos para crear el representante");


            // Excepción si ya se registró el mismo representante (por su Numero de Documento)
            if (representanteDAO.ObtenerRepXDoc(NumeroDocumento) != null)
                throw new EntidadRepetidaException("El representante ya existe");

            Representante RepresentanteACrear = new Representante();
            RepresentanteACrear.Cliente = cliente;
            RepresentanteACrear.TipoDocumento = TipoDocumento;
            RepresentanteACrear.NumeroDocumento = NumeroDocumento;
            RepresentanteACrear.Nombres = Nombres;
            RepresentanteACrear.Apellidos = Apellidos;
            RepresentanteACrear.Grupo = Grupo;
            RepresentanteACrear.Cargo = Cargo;
            return representanteDAO.Crear(RepresentanteACrear);
        }

        // Modificación del Representante
        public Representante ModificarRepresentante(Int32 CodigoRepresentante, Cliente cliente, String TipoDocumento, String NumeroDocumento, String Nombres, String Apellidos, Grupo Grupo, String Cargo)
        {
            // Excepción si falta algún dato requerido
            if (CodigoRepresentante <= 0 || cliente == null || TipoDocumento == null || NumeroDocumento == null || Nombres == null || Apellidos == null || Grupo == null || Cargo == null)
                throw new DatosInsuficientesException("Faltan datos para modificar el Representante");

            Representante representanteAModificar = new Representante();
            representanteAModificar.CodigoRepresentante = CodigoRepresentante;
            representanteAModificar.Cliente = cliente;
            representanteAModificar.TipoDocumento = TipoDocumento;
            representanteAModificar.NumeroDocumento = NumeroDocumento;
            representanteAModificar.Nombres = Nombres;
            representanteAModificar.Apellidos = Apellidos;
            representanteAModificar.Grupo = Grupo;
            representanteAModificar.Cargo = Cargo;
            return representanteDAO.Modificar(representanteAModificar);
        }

        // Eliminacion del Representante
        public void EliminarRepresentante(Int32 codigoRepresentante)
        {


            // Excepción si el representante no existe
            if (representanteDAO.Obtener(codigoRepresentante) == null)
                throw new DatosInsuficientesException("El Representante no  existe");

            Representante representanteAEliminar = new Representante();
            representanteAEliminar.CodigoRepresentante = codigoRepresentante;

            representanteDAO.Eliminar(representanteAEliminar);
        }
        #endregion

        #region Métodos de soporte para entidad Representante
        public Representante ObtenerRepresentante(Int32 CodigoRepresentante)
        {
            return representanteDAO.Obtener(CodigoRepresentante);
        }
        public ICollection<Representante> ListarRepresentante()
        {
            return representanteDAO.ListarTodos();
        }


        public Representante ObtenerRepXDoc(string nrodoc)
        {
            return representanteDAO.ObtenerRepXDoc(nrodoc);
        }


        #endregion

        //BASTANTEO___________EDWIN________________________________________________________
        #region Operaciones de negocio bastanteo
        public CBastanteo RegistrarBastanteo(Int32 CodigoGrupo, Int32 CodigoPoder, Double ImporteLimite,
                                    DateTime FechaVencimiento, string TipoIntervencion)
        {
            // Excepción si falta algún dato requerido
            if (CodigoGrupo <= 0 || CodigoPoder <= 0 || ImporteLimite <= 0 ||
                FechaVencimiento == null || TipoIntervencion == null)
                throw new DatosInsuficientesException("Faltan datos para crear el Bastanteo");
            // Excepción si ya se registrón el mismo cliente (por su RUC)
            if (bastanteoDAO.ObtenerPorGrupoPoder(CodigoGrupo, CodigoPoder) != null)
                throw new EntidadRepetidaException("La Combinacion Bastanteo ya existe");
            // Creación del Bastanteo
            CBastanteo bastanteoACrear = new CBastanteo();
            bastanteoACrear.CodigoGrupo = grupoDAO.Obtener(CodigoGrupo);
            bastanteoACrear.CodigoPoder = poderDAO.Obtener(CodigoPoder);
            bastanteoACrear.ImporteLimite = ImporteLimite;
            bastanteoACrear.FechaVencimiento = FechaVencimiento;
            bastanteoACrear.TipoIntervencion = TipoIntervencion;
            return bastanteoDAO.Crear(bastanteoACrear);
        }

        public CBastanteo EditarBastanteo(Int32 CodigoGrupo, Int32 CodigoPoder, Double ImporteLimite,
                                   DateTime FechaVencimiento, string TipoIntervencion)
        {
            // Excepción si falta algún dato requerido
            if (CodigoGrupo <= 0 || CodigoPoder <= 0 || ImporteLimite <= 0 ||
                 FechaVencimiento == null || TipoIntervencion == null)
                throw new DatosInsuficientesException("Faltan datos para crear el Bastanteo");

            CBastanteo BastanteoAModificar = new CBastanteo();
            BastanteoAModificar.CodigoGrupo = grupoDAO.Obtener(CodigoGrupo);
            BastanteoAModificar.CodigoPoder = poderDAO.Obtener(CodigoPoder);
            BastanteoAModificar.ImporteLimite = ImporteLimite;
            BastanteoAModificar.FechaVencimiento = FechaVencimiento;
            BastanteoAModificar.TipoIntervencion = TipoIntervencion;
            return bastanteoDAO.Modificar(BastanteoAModificar);
        }

        // Dirceu
        public String VerificarPoderes(String ruc, String numeroDocumento, int poder, double importe)
        {
            Representante representante = ObtenerRepXDoc(numeroDocumento);
            Int32 grupo = representante.Grupo.CodigoGrupo;
            CBastanteo bastanteo = bastanteoDAO.ObtenerPorGrupoPoder(grupo, poder);

            if (representante == null || grupo == null || bastanteo == null)
                return "El representante no tiene poder";
            
            
            DateTime vencimiento = bastanteo.FechaVencimiento;
            Double limite = bastanteo.ImporteLimite;

            if (vencimiento.CompareTo(DateTime.Now) <= 0)
                return "El poder ha vencido";

            if (limite <= importe)
                return "El importe es superior al límite";

            // tiene poder
            string mensaje, tipoIntervencion;
            if (bastanteo.TipoIntervencion == "1") { tipoIntervencion = "a sola firma "; } else { tipoIntervencion = "en conjunto con firma de "; }
            mensaje = "El representante tiene poder " + tipoIntervencion;

            foreach (BastanteoCombinacion combinacion in ListarGruposCombinacionXBastanteo(bastanteo.CodigoBastanteo))
                mensaje = mensaje + combinacion.Grupo.Descripcion + " o ";
            
            return mensaje; 
        }
        #endregion

        #region Métodos de soporte para entidad batanteo
        public CBastanteo CrearBastanteo(CBastanteo bastanteoACrear)
        {
            if (bastanteoDAO.ObtenerPorGrupoPoder(bastanteoACrear.CodigoGrupo.CodigoGrupo, bastanteoACrear.CodigoPoder.CodigoPoder) != null)
                throw new EntidadRepetidaException("El Bastanteo ya existe");
            return bastanteoDAO.Crear(bastanteoACrear);
        }

        public CBastanteo ObtenerBastanteo(Int32 codigo)
        {
            return bastanteoDAO.Obtener(codigo);
        }

        public CBastanteo ModificarBastanteo(CBastanteo bastanteoAModificar)
        {
            return bastanteoDAO.Modificar(bastanteoAModificar);
        }

        public void EliminarBastanteo(CBastanteo bastanteoAEliminar)
        {
            bastanteoDAO.Eliminar(bastanteoAEliminar);
        }

        public ICollection<CBastanteo> ListarBastanteos()
        {
            return bastanteoDAO.ListarTodos();
        }
        #endregion


        //COMBINACION________DIRCEU___________________________________________________________
        #region Operaciones de negocio combinacion
        public BastanteoCombinacion AgregarCombinacion(Int32 codigoBastanteo, Int32 codigoGrupo)
        {
            // Excepción si falta algún dato requerido
            if (codigoBastanteo <= 0 || codigoGrupo <= 0)
                throw new DatosInsuficientesException("Faltan datos para crear registro de combinación");

            // Excepción si ya se registró la misma combinación (por bastanteo y grupo)
            if (combinacionDAO.ObtenerPorBastanteoYGrupo(codigoBastanteo, codigoGrupo) != null)
            {
                throw new EntidadRepetidaException("La combinación ya existe");
            }
                        
            // Creación del registro
            BastanteoCombinacion combinacionACrear = new BastanteoCombinacion();
            combinacionACrear.CodigoBastanteo = bastanteoDAO.Obtener(codigoBastanteo);
            combinacionACrear.Grupo = grupoDAO.Obtener(codigoGrupo);
            return combinacionDAO.Crear(combinacionACrear);
        }
        #endregion

        #region Métodos de soporte para entidad BastanteoCombinacion
        public BastanteoCombinacion ObtenerCombinacion(int codigo)
        {
            return combinacionDAO.Obtener(codigo);
        }

        public BastanteoCombinacion ObtenerXBastanteoYGrupo(Int32 codigoBastanteo, Int32 codigoGrupo)
        {
            return combinacionDAO.ObtenerPorBastanteoYGrupo(codigoBastanteo, codigoGrupo);
        }

        public BastanteoCombinacion ModificarCombinacion(BastanteoCombinacion combinacionAModificar)
        {
            return combinacionDAO.Modificar(combinacionAModificar);
        }

        public void EliminarCombinacion(BastanteoCombinacion combinacionAEliminar)
        {
            combinacionDAO.Eliminar(combinacionAEliminar);
        }

        public ICollection<BastanteoCombinacion> ListarCombinacion()
        {
            return combinacionDAO.ListarTodos();
        }

        public ICollection<BastanteoCombinacion> ListarGruposCombinacionXBastanteo(Int32 codigoBastanteo)
        {
            return combinacionDAO.ListarGruposXBastanteo(codigoBastanteo); 
        }
        #endregion




    }
}